﻿using System;
using System.ComponentModel.DataAnnotations;
using System.Xml;
using System.Collections.Generic;

namespace IntellectShop.Common
{
	public partial class Hardware : Commodity
	{
		[ScaffoldColumn(false)]
		public int HardwareID { get; set; }

		[DisplayNameLocalized("Category")]
		[Required(ErrorMessage = "Hardware category is required")]
		public Common.Category Category { get; set; }

		[DisplayNameLocalized("InternalCode")]
		[Required(ErrorMessage = "Hardware Internal Code is required")]
		public string InternalCode { get; set; }

		public int CategoryID
		{
			get { return this.Category.CategoryID; }
			set { this.Category.CategoryID = value; }
		}

		[ScaffoldColumn(false)]
		public override CommodityType CommodityType
		{
			get
			{
				return Common.CommodityType.Hardware;
			}
		}

		public Hardware()
		{
			this.Category = new Common.Category();
		}

		public override string ToString()
		{
			return String.Format("{0}", this.Name);
		}

		#region Import/Export

		public static XmlDocument ExportToXml()
		{
			XmlDocument doc = new XmlDocument();
			XmlElement root = doc.CreateElement("Hardwares");
			doc.AppendChild(root);

			Dictionary<Common.Category, List<Common.Hardware>> coursesByCategory = IntellectShop.Common.Hardware.RetrieveHardwaresByCategory();
			foreach (var kvp in coursesByCategory)
			{
				foreach (var course in kvp.Value)
				{
					XmlElement courseElement = doc.CreateElement("Hardware");
					root.AppendChild(courseElement);

					courseElement.SetAttribute("CommodityID", course.CommodityID.ToString());
					courseElement.SetAttribute("CategoryName", course.Category.Name);
					courseElement.SetAttribute("InternalCode", course.InternalCode);
					courseElement.SetAttribute("Code", course.Code);
					courseElement.SetAttribute("Name", course.Name);
					courseElement.SetAttribute("Price", course.Price.Amount.ToString());
					courseElement.SetAttribute("Tags", course.TagsString);
					courseElement.SetAttribute("Description", course.Description);

					if (course.Created.HasValue)
					{
						courseElement.SetAttribute("Created", course.Created.Value.ToString("o"));
						courseElement.SetAttribute("CreatedBy", course.CreatedBy);
					}

					if (course.Updated.HasValue)
					{
						courseElement.SetAttribute("Updated", course.Updated.Value.ToString("o"));
						courseElement.SetAttribute("UpdatedBy", course.UpdatedBy);
					}
				}
			}

			return doc;
		}

		public static void ImportFromXml(XmlDocument doc, bool setNotActive, string actionBy)
		{
			if (doc == null)
			{
				throw new ArgumentNullException("Hardware.ImportFromXml, doc == null");
			}

			List<int> updatesCommodity = new List<int>();
			XmlNode empty = doc.CreateElement("Empty");
			XmlNodeList hardwaresElements = doc.SelectNodes("//Hardware");
			foreach (XmlNode node in hardwaresElements)
			{
				Hardware hard = new Hardware();
				string code = String.Empty;
				string internalCode = String.Empty;
				try
				{
					code = (node.SelectSingleNode("@Code") ?? empty).Value;
					if (String.IsNullOrEmpty(code))
					{
						throw new ArgumentNullException("Не задан код товара.");
					}

					internalCode = (node.SelectSingleNode("@InternalCode | @AXAPTA") ?? empty).Value;
					if (String.IsNullOrEmpty(internalCode))
					{
						internalCode = code;
					}

					Commodity com = Commodity.RetrieveByCode(code);
					if (com == null)
					{
						hard.Code = code;
					}
					else
					{
						hard = Hardware.RetrieveByCommodityID(com.CommodityID);
					}

					hard.InternalCode = internalCode;

					string categoryName = (node.SelectSingleNode("@CategoryName") ?? empty).Value;
					if (String.IsNullOrEmpty(categoryName))
					{
						throw new ArgumentNullException(String.Format("Не задана категория товара {0}.", code));
					}

					Category category = Category.RetrieveByName(categoryName);
					if (category == null)
					{
						category = new Category();
						category.Name = categoryName;
						category.Create(actionBy);
					}

					hard.Category = category;
					hard.CategoryID = category.CategoryID;

					if (node.SelectSingleNode("@Name") != null)
					{
						hard.Name = node.SelectSingleNode("@Name").Value;
					}

					decimal amount;
					if (Decimal.TryParse((node.SelectSingleNode("@Price") ?? empty).Value, out amount))
					{
						hard.Price = new Common.Money { Amount = amount, Currency = Currency.RUB };
					}

					if (node.SelectSingleNode("@Tags") != null)
					{
						hard.TagsString = node.SelectSingleNode("@Tags").Value;
					}

					if (node.SelectSingleNode("@Description") != null)
					{
						hard.Description = node.SelectSingleNode("@Description").Value;
					}

					if (hard.CommodityID == 0)
					{
						hard.Create(actionBy);
					}
					else
					{
						hard.Update(actionBy);
					}

					updatesCommodity.Add(hard.CommodityID);
				}
				catch (Exception e)
				{
					throw new Exception(
						String.Format("Ошибка в товаре Code={0}, InternalCode={1}", code, internalCode),
						e);
				}
			}

			if (setNotActive)
			{
				Hardware.SetNotActiveExclude(updatesCommodity);
			}
		}

		#endregion
	}
}
